package chain_user_cofnig

import (
	"chain_bridge_service/configs"
	"context"
	"fmt"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

func NewModel() *ChainUserConfig { return new(ChainUserConfig) }

func (c *ChainUserConfig) List(client *mongo.Client) ([]ChainUserConfig, error) {
	var list []ChainUserConfig
	cfg := configs.Get().Mongodb
	keyClient := client.Database(cfg.Config.Name).Collection("chain_user_config")
	find, err := keyClient.Find(context.TODO(), bson.D{{"chainConfigId", c.ChainConfigId}})
	if err != nil {
		return nil, err
	}
	err = find.All(context.TODO(), &list)
	if err != nil {
		return nil, err
	}
	return list, nil
}

func (c *ChainUserConfig) GetConfigByUserId(client *mongo.Client, pageIndex uint, pageSize uint) ([]ChainUserConfig, error) {

	cfg := configs.Get().Mongodb
	var chainUserConfigList []ChainUserConfig
	applyClient := client.Database(cfg.Config.Name).Collection("chain_user_config")
	skip := int64((pageIndex - 1) * pageSize)
	findOptions := options.Find()
	findOptions.SetSort(bson.D{{"_id", -1}})
	findOptions.SetSkip(skip)
	findOptions.SetLimit(int64(pageSize))
	find, err := applyClient.Find(context.TODO(), bson.M{"userId": c.UserId}, findOptions)
	if err != nil {
		return nil, err
	}
	err = find.All(context.TODO(), &chainUserConfigList)
	if err != nil {
		return nil, err
	}

	return chainUserConfigList, nil
}

func (c *ChainUserConfig) Count(client *mongo.Client) (int64, error) {
	cfg := configs.Get().Mongodb
	applyClient := client.Database(cfg.Config.Name).Collection("chain_user_config")
	count, err := applyClient.CountDocuments(context.TODO(), bson.M{"userId": c.UserId})
	if err != nil {
		return 0, err
	}
	return count, nil
}

func (c *ChainUserConfig) Create(client *mongo.Client) error {
	cfg := configs.Get().Mongodb
	keyClient := client.Database(cfg.Config.Name).Collection("chain_user_config")
	_, err := keyClient.InsertOne(context.TODO(), c)
	return err
}

func (c *ChainUserConfig) Delete(db *mongo.Client) error {
	cfgs := configs.Get().Mongodb
	pictureClient := db.Database(cfgs.Config.Name).Collection("chain_user_config")
	objId, err := primitive.ObjectIDFromHex(c.Id)
	if err != nil {
		return fmt.Errorf("invalid ID format: %v", err)
	}
	_, err1 := pictureClient.DeleteOne(context.TODO(), bson.D{{"_id", objId}})
	if err1 != nil {
		return err1
	}
	return err
}

func (c *ChainUserConfig) GetById(client *mongo.Client) (*mongo.Cursor, error) {
	cfg := configs.Get().Mongodb
	applyClient := client.Database(cfg.Config.Name).Collection("chain_user_config")
	find, err := applyClient.Find(context.TODO(), bson.M{"_id": c.Id})
	if err != nil {
		return nil, err
	}

	return find, nil
}

func (c *ChainUserConfig) Upate(client *mongo.Client) error {

	cfg := configs.Get().Mongodb
	applyClient := client.Database(cfg.Config.Name).Collection("chain_user_config")
	objId, _ := primitive.ObjectIDFromHex(c.Id)
	update := bson.M{"collectAddress": c.CollectAddress, "feeAddress": c.FeeAddress,
		"chainConfigId": c.ChainConfigId}
	_, err := applyClient.UpdateOne(context.TODO(), bson.M{"_id": objId}, bson.M{"$set": update})
	return err
}

func FindOne(client *mongo.Client, userId string, chainConfigId string) (ChainUserConfig, error) {
	var data ChainUserConfig
	cfg := configs.Get().Mongodb
	applyClient := client.Database(cfg.Config.Name).Collection("chain_user_config")
	filter := bson.M{
		"userId":        userId,
		"chainConfigId": chainConfigId,
	}
	err := applyClient.FindOne(context.TODO(), filter).Decode(&data)
	return data, err
}

func (c *ChainUserConfig) GetInfoById(client *mongo.Client) (ChainUserConfig, error) {
	var chainUserConfig ChainUserConfig
	cfg := configs.Get().Mongodb
	applyClient := client.Database(cfg.Config.Name).Collection("chain_user_config")
	objId, _ := primitive.ObjectIDFromHex(c.Id)
	err := applyClient.FindOne(context.TODO(), bson.M{"_id": objId}).Decode(&chainUserConfig)

	return chainUserConfig, err
}
